using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Security;
using System.Drawing.Printing;
using System.ComponentModel;

namespace qPrintComponent
{
    public abstract class qSafePrinterInfo : qSafeInfo
    {
        
        protected qSafePrinterInfo(SafeHandle PrinterHandle, int level)
            :base(PrinterHandle, level)
        {            
        }

        [PrintingPermission(SecurityAction.Demand, Level = PrintingPermissionLevel.DefaultPrinting)]
        protected override void RefreshInfo()
        {
            if (!qStatic.GetPrinter(PrinterHandle, Level, handle, Size, out BytesNeeded) && (BytesNeeded > 0))
            {
                AllocMem();
                if (!qStatic.GetPrinter(PrinterHandle, Level, handle, Size, out BytesNeeded) && (BytesNeeded > 0))
                    throw new Win32Exception(GetType().FullName + Level.ToString(System.Globalization.CultureInfo.InvariantCulture) + " Error");
            }
        }

        [PrintingPermission(SecurityAction.Demand, Level = PrintingPermissionLevel.AllPrinting)]
        private bool UpdatePrinter(int printerLevel, IntPtr memhandle, PrinterControl pc)
        {
            if (!PrintComponent.SafePrinterHandle.canUpdate)
            {
                System.Windows.Forms.MessageBox.Show("Can not Update");
                return false;
            }
            if (this.IsInvalid)
                throw new InvalidOperationException("Invalid memoryhandle");
            if (PrinterSafeHandle.IsInvalid)
                throw new InvalidOperationException("Printer SafeHandle Invalid");
            bool b = qStatic.SetPrinter(PrinterHandle, printerLevel, memhandle, pc);
            if (!b)
                throw new Win32Exception("Printer NOT Updated. Reason:" + Marshal.GetLastWin32Error().ToString(System.Globalization.CultureInfo.InvariantCulture));
            this.RefreshInfo();
            return b;
        }

        public bool PausePrinter()
        {
            return UpdatePrinter(0, IntPtr.Zero, PrinterControl.Pause);
        }
        public bool ResumePrinter()
        {
            return UpdatePrinter(0, IntPtr.Zero, PrinterControl.Resume);
        }
        public bool PurgePrinter()
        {
            return UpdatePrinter(0, IntPtr.Zero, PrinterControl.Purge);
        }
        protected override bool Update()
        {
            return UpdatePrinter(Level, this.handle, PrinterControl.Nul);
        }
        
    }
}
